<?
/**
 * Webapp Functions
 */

/**
 * Add a new item when adding or editing items.
 * @param HistoryTimelineDbo itemDbo
 * @param string itemType
 * @param string idProp
 * @param string nameProp
 * @param string requestVar
 * @return mixed
 *   string error message on failures
 *   bool true on success
 */
function addNewListItem(&$itemDbo = null, $itemType = null, $idProp = null,
                        $nameProp = null, $requestVar = null) {
	global $_APP;
	if (!($itemDbo instanceof HistoryTimelineDbo)) {
		return 'Invalid instance specified.';
		}
	if (!is_string($itemType) or !strlen($itemType)) {
		return 'Invalid item type specified.';
		}
	if (!is_string($nameProp) or !strlen($nameProp)) {
		return 'Invalid name property specified.';
		}
	if (!is_string($requestVar) or !strlen($requestVar)) {
		return 'Invalid request variable name specified.';
		}
	$newItem = (isset($_REQUEST[$requestVar])) ? trim($_REQUEST[$requestVar]) : '';
	if (!is_string($newItem) or !strlen($newItem)) { return true; }

	// Get dbo object
	$v = getDbo($itemType);
	if (!($v instanceof HistoryTimelineDbo)) {
		return 'Failed to get item instance.';
		}
	$v->resetProperties();
	$v->setProperty($nameProp, $newItem);
	$v->populated = true;
	$rc = $v->add();
	if (!($rc === true)) {
		return $rc;
		}
	$rc = $itemDbo->setProperty($idProp, $v->getProperty('Id'));
	if ($rc === true) {
		$_REQUEST[$requestVar] = '';
		// Log it
		$m = 'add list item type(' . $itemType . ') value(' . $newItem . ')';
		$_APP->log->log_audit($m);
		return true;
		}
	return $rc;
	}

/**
 * Get date picker form element
 * @param string presetDate
 * @param int calNum
 *   Use when multiple calendars exist on the same form.
 * @return string
 */
function getDatePicker($presetDate = null, $calNum = '1') {
	// Validate the calendar number...
	if (!is_numeric($calNum) or $calNum < 1) { return PHP_EOL; }
	$bf = 'element_' . $calNum;
	$img = 'cal_img_' . $calNum;
	$da = 'calendar_' . $calNum;
	// User specified a preset date
	if (is_string($presetDate) and strlen($presetDate) == 19) {
		$_REQUEST[$bf . '_1'] = substr($presetDate, 5, 2);
		$_REQUEST[$bf . '_2'] = substr($presetDate, 8, 2);
		$_REQUEST[$bf . '_3'] = substr($presetDate, 0, 4);
		}
	$m = (isset($_REQUEST[$bf . '_1'])) ? $_REQUEST[$bf . '_1'] : date('m');
	$d = (isset($_REQUEST[$bf . '_2'])) ? $_REQUEST[$bf . '_2'] : date('j');
	$y = (isset($_REQUEST[$bf . '_3'])) ? $_REQUEST[$bf . '_3'] : date('Y');
	$h = array();
	$h[] = '<input id="' . $bf . '_1" name="' . $bf . '_1" size="2" maxlength="2" value="' . $m . '" type="text">MM';
	$h[] = '<input id="' . $bf . '_2" name="' . $bf . '_2" size="2" maxlength="2" value="' . $d . '" type="text">DD';
	$h[] = '<input id="' . $bf . '_3" name="' . $bf . '_3" size="4" maxlength="4" value="' . $y . '" type="text">YYYY';
	$h[] = '<span id="calendar_1">';
	$h[] = '<img id="' . $img . '" class="datepicker" src="images/calendar.gif" alt="Pick a date.">';
	$h[] = '</span>';
	$h[] = '<script type="text/javascript">';
	$h[] = '	Calendar.setup({';
	$h[] = '	inputField	 : "' . $bf . '_3",';
	$h[] = '	baseField    : "' . $bf . '",';
	$h[] = '	displayArea  : "' . $da . '",';
	$h[] = '	button		 : "' . $img . '",';
	$h[] = '	ifFormat	 : "%B %e, %Y",';
	$h[] = '	onSelect	 : selectDate';
	$h[] = '	});';
	$h[] = '</script>';
	return implode($h, PHP_EOL) . PHP_EOL;
	}

/**
 * Convert date string (YYYY-MM-DD) to english date string.
 * @param string dateTxt
 * @return string dateStr
 */
function getDateString($dateTxt = null) {
	if (!is_string($dateTxt) or strlen($dateTxt) !== 10) { return ''; }
	$ts = strtotime($dateTxt);
	if ($ts === false) { return ''; }
	return date('F j, Y', $ts);
	}

/**
 * Return a timestamp based on selections from the date picker element.
 * @param int calNum
 * @return mixed
 *   string datetime on success
 *   bool false on failures
 */
function getFromDatePicker($calNum = '1') {
	// Validate the calendar number...
	if (!is_numeric($calNum) or $calNum < 1) { return PHP_EOL; }
	$bf = 'element_' . $calNum;
	$m = (isset($_REQUEST[$bf . '_1'])) ? $_REQUEST[$bf . '_1'] : 0;
	$d = (isset($_REQUEST[$bf . '_2'])) ? $_REQUEST[$bf . '_2'] : 0;
	$y = (isset($_REQUEST[$bf . '_3'])) ? $_REQUEST[$bf . '_3'] : 0;
	if (!checkdate($m, $d, $y)) { return false; }
	$ts = mktime(0, 0, 0, $m, $d, $y);
	return date('Y-m-d', $ts);
	}

/**
 * Obtain database connection object, re-use existing objects
 * @param string objectType
 * @param mixed moduleArgs
 * @return mixed
 */
function &getDbo($objectType = null, $moduleArgs = null) {
	global $_DBO;
	if (!isset($_DBO) or !is_array($_DBO)) { $_DBO = array(); }
	$err   = false;
	$class = false;

	// Already have one instantiated...
	if (isset($_DBO[$objectType])) {
		return $_DBO[$objectType];
		}

	// Do we have the master class yet?
	if (!isset($_DBO['master'])) {
		// required defines?
		if (!defined('DB_HOST')) { return $err; }
		if (!defined('DB_USER')) { return $err; }
		if (!defined('DB_NAME')) { return $err; }
		if (!defined('DB_PASS')) { return $err; }
		// bring up the master instance
		$d = new HistoryTimelineDbo();
		if (!($d instanceof HistoryTimelineDbo)) { return $err; }
		$d->setDatabaseHost(DB_HOST);
		$d->setDatabase(DB_NAME);
		$d->setDatabaseUser(DB_USER);
		$d->setDatabasePass(DB_PASS);
		if (!($d->requireDatabase() === true)) { return $err; }
		$_DBO['master'] = &$d;
		unset($d);
		}

	// Are they wanting a base dbo object?
	if ($objectType == 'HistoryTimelineDbo') { return $_DBO['master']; }

	// Get a copy from the master...
	$dbo = $_DBO['master']->getDbo($objectType, $moduleArgs);
	if (!($dbo instanceof $objectType)) { return $err; }

	// Store it for repeat calls.
	$_DBO[$objectType] = &$dbo;
	unset($dbo);

	// Return it.
 	return $_DBO[$objectType];
	}

/**
 * Get standard download list of properties for common object types.
 * @param dbo $dbo
 * @return array $props
 */
function getListDownloadProperties(&$dbo = null) {
	$props = array();
	if (!is_object($dbo)) { return $props; }
	switch(get_class($dbo)) {
		case 'Log':
			$props = getDbo('Log')->getPropertyList();
		break;
		case 'User':
			// everything but password...
			$props = array();
			foreach(getDbo('User')->getPropertyList() as $prop) {
				if ($prop == 'Password') { continue; }
				$props[] = $prop;
				}
		break;
		default:
			$props = array();
			foreach($dbo->getPropertyList() as $prop) {
				$props[] = $prop;
				}
		break;
		}
	return $props;
	}

/**
 * Get the admin menu bar
 * @param string currentPage
 * @return string
 */
function getMenuBarAdmin($currentPage = null) {
	// too much clutter, just use the regular menu bar
	return getMenuBarMain($currentPage);
	}

/**
 * Get the admin menu bar
 * @param string currentPage
 * @return string
 */
function getMenuBarMain($currentPage = null) {
	$mb = new menuBar($currentPage);
	$mb->addToLeft(getMenubarLink(OPT_HOME, $currentPage));
	$mb->addToLeft(getMenubarLink(OPT_EVENTS, $currentPage));
	hasAccess('Admin') && $mb->addToRight(getMenubarLink(OPT_ADMIN, $currentPage));
	$mb->addToRight(getMenubarLink(OPT_PASSCHANGE, $currentPage));
	$mb->addToRight(getMenubarLink(OPT_LOGOUT, $currentPage));
	return $mb->get();
	}

/**
 * Get predefined menubar link
 * @param string $linkOpt
 * @param string $currentOpt
 * @return menuLink
 */
function getMenubarLink($linkOpt = null, $currentPage = null) {
	global $_APP;

	switch($linkOpt) {
		case OPT_ADMIN:
			$qs = $_APP->html->getAppletQs(APPLET_ADMIN);
			$img = 'images/Admin32.png';
		break;
		case OPT_ADMIN_CATEGORIES:
			$qs  = $_APP->html->getAppletQs(APPLET_ADMIN_CATEGORIES);
			$img = 'images/Database32.png';
		break;
		case OPT_ADMIN_SOURCES:
			$qs  = $_APP->html->getAppletQs(APPLET_ADMIN_SOURCES);
			$img = 'images/Database32.png';
		break;
		case OPT_ADMIN_USERS:
			$qs  = $_APP->html->getAppletQs(APPLET_ADMIN_USERS);
			$img = 'images/user32.png';
		break;
		case OPT_EVENTS:
			$qs  = $_APP->html->getAppletQs(APPLET_EVENTS);
			$img = 'images/Database32.png';
		break;
		case OPT_HOME:
			$qs  = './';
			$img = 'images/home32.png';
		break;
		case OPT_LOG:
			$qs  = $_APP->html->getAppletQs(APPLET_LOG);
			$img = 'images/log32.png';
		break;
		case OPT_LOGOUT:
			$qs  = $_APP->html->getActionQs(ACTION_LOGOUT);
			$img = 'images/logout32.png';
		break;
		case OPT_PASSCHANGE:
			$qs  = $_APP->html->getActionQs(ACTION_PASSCHANGE);
			$img = 'images/password32.png';
		break;
		default:
			return new menuLink();
		break;
		}
	return new menuLink($qs, $img, $linkOpt, ($currentPage == $linkOpt));
	}

/**
 * Get the main menu.
 */
function getPageMainMenu() {
	global $_APP;
	requireWebApp();

	// Load the template
	die($_APP->html->getTemplate('main.menu.php'));
	}

/**
 * Get ID of authenticated user.
 * @param string propName
 * @return mixed
 */
function getUserId() {
	global $_APP;
	return $_APP->sess->getUserData('Id');
	}

/**
 * Get property of authenticated user.
 * @param string propName
 * @return mixed
 */
function getUserProperty($propName = null) {
	global $_APP;
	if (!is_string($propName)) { return ''; }
	return $_APP->sess->getUserData($propName);
	}

/**
 * Obtain singleton webapp instance
 */
function &getWebApp() {
	global $_APP;
	if (isset($_APP) and $_APP instanceof webapp) { return $_APP; }
	// Instantiate for the first time...
	$_APP = new webapp();
	$_APP->moduleRequired('auth,html,log,sess');
	return $_APP;
	}

/**
 * Does currently authenticated user have specified access rights?
 * @param string aclName
 * @return bool
 */
function hasAccess($aclName = null) {
	// Admins are god ;)
	if (isAdmin()) { return true; }
	// Now for the mere mortals
	switch(strtolower($aclName)) {
		case 'viewer':
			return isViewer();
		break;
		default:
			return false;
		break;
		}
	}

/**
 * Getters to determine access level of authenticated user.
 */
function isAdmin() {
	return (getUserProperty('IsAdmin') == '1');
	}
function isViewer() {
	// if they can login, they have view only access
	return true;
	}

/**
 * Require specified access level, or die trying ;)
 * @param string aclName
 */
function requireAccess($aclName = null) {
	$levels = explode(',', $aclName);
	foreach($levels as $lvl) {
		if (hasAccess($lvl)) { return; }
		}
	die('Access denied, contact an administrator.');
	}

/**
 * Require webapp instance or die trying
 */
function requireWebApp() {
	global $_APP;
	if (!isset($_APP) or !($_APP instanceof webapp)) {
		die('FATAL ERROR: webapp object required.');
		}
	}

/**
 * Draw select box to select a category id
 * @param string inputName
 * @param string $default
 * @param string $inputArgs
 * @return string
 */
function selectCategoryId($inputName = null, $default = null, $inputArgs = null) {
	if (!is_string($inputName)) { return PHP_EOL; }
	$ar = getDbo('Category')->getList();
	if (!is_array($ar) or !count($ar)) { return 'Add Categories!'; }
	$txt = '<select name="' . $inputName . '" id="' . $inputName . '"';
	if (is_string($inputArgs)) { $txt .= ' ' . $inputArgs; }
	$txt .= '>';
	$h = array($txt);
	foreach($ar as &$val) {
		$sel = ($val['Id'] == $default) ? ' selected=true' : '';
		$h[] = '<option value="' . $val['Id'] . '"' . $sel . '>'
		     . htmlspecialchars($val['Tag']) . '</option>';
		}
	$h[] = '</select>';
	return implode(PHP_EOL, $h) . PHP_EOL;
	}

/**
 * Draw select box to select a source id
 * @param string inputName
 * @param string $default
 * @param string $inputArgs
 * @return string
 */
function selectSourceId($inputName = null, $default = null, $inputArgs = null) {
	if (!is_string($inputName)) { return PHP_EOL; }
	$ar = getDbo('Source')->getList();
	if (!is_array($ar) or !count($ar)) { return 'Add Sources!'; }
	$txt = '<select name="' . $inputName . '" id="' . $inputName . '"';
	if (is_string($inputArgs)) { $txt .= ' ' . $inputArgs; }
	$txt .= '>';
	$h = array($txt);
	foreach($ar as &$val) {
		$sel = ($val['Id'] == $default) ? ' selected=true' : '';
		$h[] = '<option value="' . $val['Id'] . '"' . $sel . '>'
		     . '(' . $val['Id'] . ') '
		     . htmlspecialchars($val['Source']) . '</option>';
		}
	$h[] = '</select>';
	return implode(PHP_EOL, $h) . PHP_EOL;
	}

/**
 * Draw select box to select enabled or disabled
 * @param string selectboxName
 * @param string default
 * @return string
 */
function selectEnabledOrDisabled($selectboxName = null, $default = null) {
	if (!is_string($selectboxName) or !strlen($selectboxName)) { return PHP_EOL; }
	$h = array('<select name="' . $selectboxName . '">');
	$opts = array('0' => 'Disabled', '1' => 'Enabled');
	foreach($opts as $num => $txt) {
		$sel = ($num == $default) ? ' selected' : '';
		$h[] = '<option value="' . $num . '"' . $sel . '>' . $txt . '</option>';
		}
	$h[] = '</select>';
	return implode(PHP_EOL, $h) . PHP_EOL;
	}

/**
 * Draw select box to select yes or no
 * @param string selectboxName
 * @param string default
 * @return string
 */
function selectYesOrNo($selectboxName = null, $default = null) {
	if (!is_string($selectboxName) or !strlen($selectboxName)) { return PHP_EOL; }
	$h = array('<select name="' . $selectboxName . '">');
	$opts = array('0' => 'No', '1' => 'Yes');
	foreach($opts as $num => $txt) {
		$sel = ($num == $default) ? ' selected' : '';
		$h[] = '<option value="' . $num . '"' . $sel . '>' . $txt . '</option>';
		}
	$h[] = '</select>';
	return implode(PHP_EOL, $h) . PHP_EOL;
	}

/**
 * Trim text string to specified length, include elipsis
 * @param string text
 * @param int len
 */
function trimText(&$text = null, $len = 100) {
	if (!is_string($text) or strlen($text) <= $len) { return $text; }
	return substr($text, 0, $len) . '...';
	}

?>
